package com.xupypr.surgery.server;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import org.datanucleus.store.exceptions.NoTableManagedException;

import com.google.appengine.api.datastore.Text;
import com.xupypr.surgery.client.objects.BlogEntry;
import com.xupypr.surgery.server.objects.JDOBlogEntry;

public class Persistence {
	private static final PersistenceManagerFactory pmfInstance = JDOHelper
			.getPersistenceManagerFactory("transactions-optional");

	private Persistence() {
	}

	public static PersistenceManagerFactory get() {
		return pmfInstance;
	}

	/**
	 * Поскольку GAE не позволяет извлекать со смещением больше 1000, то будем
	 * использовать хитрости, получая записи по дате.
	 * 
	 * @param page
	 * @param quantity
	 * @return
	 */
	public static List<BlogEntry> getEntries(Date dateBorder, Long quantity) {
		PersistenceManager pm = get().getPersistenceManager();

		Query query = pm.newQuery(JDOBlogEntry.class);
		query.setFilter("created < dateBorder");
		query.setOrdering("created desc");
		query.declareImports("import java.util.Date");
		query.declareParameters("java.util.Date dateBorder");
		query.setRange(0, quantity);

		List<BlogEntry> result = new ArrayList<BlogEntry>();
		try {
			List<JDOBlogEntry> qresult = getEntries(dateBorder, pm, query);
			for (JDOBlogEntry be : qresult) {
				result.add(JDOBlogEntry.fromPersistable(be, false));
			}
		} finally {
			pm.close();
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	private static List<JDOBlogEntry> getEntries(Date dateBorder,
			PersistenceManager pm, Query query) {
		try {
			return (List<JDOBlogEntry>) pm.newQuery(query).execute(dateBorder);
		} catch (NoTableManagedException ex) {
			return new ArrayList<JDOBlogEntry>();
		}
	}

	public static void createEntry(BlogEntry entry) {
		PersistenceManager pm = get().getPersistenceManager();
		pm.makePersistent(JDOBlogEntry.toPersistable(entry, true));
		pm.close();
	}

	public static void updateEntry(BlogEntry newEntry) {
		if (newEntry.getId() != null) {
			PersistenceManager pm = get().getPersistenceManager();
			
			JDOBlogEntry entry = pm.getObjectById(JDOBlogEntry.class, newEntry.getId());
			
			entry.setCaption(newEntry.getCaption());
			entry.setLastModified(new Date());
			entry.setCuttedText(new Text(newEntry.getText()));
			entry.setText(new Text(newEntry.getText()));
			
			pm.close();
		}
	}

	public static void deleteEntry(Long id) {
		PersistenceManager pm = get().getPersistenceManager();
		JDOBlogEntry entry = pm.getObjectById(JDOBlogEntry.class, id);
		if (entry != null) {
			pm.deletePersistent(entry);
		}
		pm.close();
	}

	public static BlogEntry getEntry(Long id) {
		PersistenceManager pm = get().getPersistenceManager();
		JDOBlogEntry entry = pm.getObjectById(JDOBlogEntry.class, id);

		BlogEntry result = JDOBlogEntry.fromPersistable(entry, true);
		pm.close();
		return result;
	}
}
